fix: newsletter editor formatting and working group activity#2000
Merged
fix: newsletter editor formatting and working group activity#2000
Conversation
Editor's note was losing all formatting when pasting rich text because the save function used textContent which strips line breaks. Now uses innerText and a paste handler that preserves paragraph structure and converts links to Slack format. Working groups in "From the Inside" now show meeting recaps and active threads instead of just a summary description. Groups without actual recent activity (meetings or threads) are filtered out. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CodeQL flagged the DOMParser-based HTML paste handler as a potential XSS vector. Simplified to use text/plain from clipboard which preserves line breaks without any HTML processing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pasting rich text now preserves links by extracting href/label pairs from clipboard HTML and converting to Slack format. Uses text/plain as the base (safe) and only reads link data from the parsed DOM without modifying it, avoiding the CodeQL taint flow. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CodeQL flags any DOMParser usage with clipboard data as js/xss. Using plain text/plain from clipboard is sufficient to preserve line breaks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces the plain contenteditable div with a TipTap-based rich text editor for the editor's note field. Supports bold, italic, links, and bullet/ordered lists with a toolbar UI. - Bundle TipTap core + starter-kit + link extension via esbuild - Store HTML in editorsNote field (backward compat with plain text) - Sanitize HTML server-side with DOMPurify (allowlist of safe tags) - Email rendering adds inline styles for email client compatibility - Slack rendering converts HTML to mrkdwn format - Increase MAX_TEXT_LENGTH from 500 to 2000 for HTML overhead Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TipTap is only used by the build script (scripts/build-tiptap.mjs) and the bundle is committed as server/public/vendor/tiptap.js. No need for these deps in the Docker build. Regenerated lockfile with Node 20 to fix pre-existing npm ci sync issue in Docker. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The isHtml check was matching Slack-format links (<https://...>) as HTML because the regex was too broad. Narrowed to only match actual HTML tags (p, div, br, strong, em, ul, ol, li, a). Added DOMPurify.sanitize before HTML-to-text conversions to satisfy CodeQL's incomplete-sanitization and double-escaping checks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace regex-based HTML tag stripping with DOMPurify RETURN_DOM + recursive DOM traversal. CodeQL cannot trace safety through DOMPurify's sanitize-then-regex pattern, but DOM traversal avoids the flagged regex patterns entirely. Also use TipTap's isEmpty API instead of regex for empty check. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
innerTextinstead oftextContentso line breaks survive save/render.<br>in the email template.safeHref()protocol validation on all dynamichrefattributes to preventjavascript:URI injection.Test plan
🤖 Generated with Claude Code